﻿#include <graphics.h>
#include <vector>
#include <string>
#include <ctime>
#include <algorithm>
#include <random>
#include <sstream>
#include <thread>

enum Suit { HEARTS, DIAMONDS, CLUBS, SPADES };

const std::string RANKS[] = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A" };

class Card {
public:
    Suit suit;
    std::string rank;
    int value;
};

class Deck {
private:
    std::vector<Card> cards;

public:
    Deck() {
        addNewDeck();
        shuffle();
    }

    void addNewDeck() {
        cards.clear();
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 13; j++) {
                Card card;
                card.suit = static_cast<Suit>(i);
                card.rank = RANKS[j];
                card.value = (j < 9) ? (j + 2) : 10;
                cards.push_back(card);
            }
        }
    }

    void shuffle() {
        std::random_device rd;
        std::mt19937 g(rd());
        std::shuffle(cards.begin(), cards.end(), g);
    }

    Card dealCard() {
        if (cards.empty()) {
            addNewDeck();
            shuffle();
        }
        Card card = cards.back();
        cards.pop_back();
        return card;
    }

    bool needReshuffle() {
        return cards.size() < 10;
    }
};

class Player {
protected:
    std::vector<Card> hand;
    int score;

public:
    Player() : score(0) {}

    void clearHand() {
        hand.clear();
        score = 0;
    }

    void addCard(const Card& card) {
        hand.push_back(card);
        updateScore();
    }

    const std::vector<Card>& getHand() const {
        return hand;
    }

    int getScore() const {
        return score;
    }

    bool hasFiveCardsNotBust() const {
        return hand.size() >= 5 && score <= 21;
    }

private:
    void updateScore() {
        score = 0;
        int aces = 0;

        for (const Card& card : hand) {
            if (card.rank == "A") {
                aces++;
                score += 11;
            }
            else {
                score += card.value;
            }
        }

        while (score > 21 && aces > 0) {
            score -= 10;
            aces--;
        }
    }
};

class MainMenu {
private:
    static IMAGE imgBackground;
    static IMAGE imgCardBack;

public:
    static bool show();
    static void loadResources();
    static IMAGE& getCardBackImage() { return imgCardBack; }

private:
    static void drawButtons();
    static bool isMouseOverButton(int bx, int by, int bw, int bh, const ExMessage& msg);
    static void clearScreen();
    static void drawBoldText(int x, int y, const TCHAR* text, int size);
    static void drawRulesScreen();
};

IMAGE MainMenu::imgBackground;
IMAGE MainMenu::imgCardBack;

void MainMenu::loadResources() {
    loadimage(&imgBackground, _T("image\\background.jpg"), 800, 600);
    loadimage(&imgCardBack, _T("image\\card_back.png"), 100, 140);
}

void MainMenu::drawBoldText(int x, int y, const TCHAR* text, int size) {
    settextstyle(size, 0, _T("Consolas"));
    settextcolor(WHITE);
    setbkmode(TRANSPARENT);

    for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
            if (i != 0 || j != 0) {
                outtextxy(x + i, y + j, text);
            }
        }
    }
    outtextxy(x, y, text);
}

void MainMenu::drawRulesScreen() {
    clearScreen();
    settextstyle(20, 0, _T("Consolas"));
    settextcolor(BLACK);

    int y = 50;
    outtextxy(50, y, _T("21点游戏规则:"));
    y += 30;
    outtextxy(50, y, _T("1. 目标尽可能接近21点"));
    y += 30;
    outtextxy(50, y, _T("2. J/Q/K各为10点，A可为1或11点"));
    y += 30;
    outtextxy(50, y, _T("3. 可选择要牌(再拿一张)或停牌(停止)"));
    y += 30;
    outtextxy(50, y, _T("4. 庄家必须拿到至少17点才能停止"));
    y += 30;
    outtextxy(50, y, _T("5. 超过21点即为爆牌"));
    y += 30;
    outtextxy(50, y, _T("6. 若玩家点数比庄家高且未爆，获得赌注筹码"));
    y += 30;
    outtextxy(50, y, _T("7. 初始有100筹码，每次下注10筹码"));
    y += 30;
    outtextxy(50, y, _T("8. 可点击'加注'将当前赌注翻倍(每局仅一次)"));
    y += 30;
    outtextxy(50, y, _T("9. 达到200筹码即赢得游戏"));
    y += 30;
    outtextxy(50, y, _T("10. 筹码不足10时游戏失败"));
    y += 30;
    outtextxy(50, y, _T("11. 手牌达到5张且未爆牌将自动获胜"));
    y += 50;

    setfillcolor(WHITE);
    setlinecolor(BLACK);
    fillrectangle(300, y, 500, y + 50);
    rectangle(300, y, 500, y + 50);
    int textWidth = textwidth(_T("返回主菜单"));
    outtextxy(400 - textWidth / 2, y + 15, _T("返回主菜单"));
}

void MainMenu::drawButtons() {
    clearScreen();
    setbkcolor(RGB(50, 50, 100));
    cleardevice();

    putimage(0, 0, &imgBackground);

    int titleWidth = textwidth(_T("21点"));
    drawBoldText(360 - titleWidth / 2, 100, _T("21点"), 56);

    setfillcolor(WHITE);
    setlinecolor(BLACK);
    settextcolor(BLACK);
    settextstyle(20, 0, _T("Consolas"));

    fillrectangle(300, 200, 500, 250);
    rectangle(300, 200, 500, 250);
    int startTextWidth = textwidth(_T("开始游戏"));
    outtextxy(400 - startTextWidth / 2, 215, _T("开始游戏"));

    fillrectangle(300, 300, 500, 350);
    rectangle(300, 300, 500, 350);
    int ruleTextWidth = textwidth(_T("游戏规则"));
    outtextxy(400 - ruleTextWidth / 2, 315, _T("游戏规则"));

    fillrectangle(300, 400, 500, 450);
    rectangle(300, 400, 500, 450);
    int exitTextWidth = textwidth(_T("退出游戏"));
    outtextxy(400 - exitTextWidth / 2, 415, _T("退出游戏"));
}

bool MainMenu::isMouseOverButton(int bx, int by, int bw, int bh, const ExMessage& msg) {
    return (msg.x >= bx && msg.x <= bx + bw && msg.y >= by && msg.y <= by + bh);
}

void MainMenu::clearScreen() {
    setbkcolor(WHITE);
    cleardevice();
}

bool MainMenu::show() {
    ExMessage msg;
    while (true) {
        drawButtons();
        FlushBatchDraw();

        while (true) {
            while (!peekmessage(&msg, EX_MOUSE));

            if (msg.message == WM_LBUTTONDOWN) {
                if (isMouseOverButton(300, 200, 200, 50, msg)) {
                    return false;
                }
                else if (isMouseOverButton(300, 300, 200, 50, msg)) {
                    drawRulesScreen();
                    FlushBatchDraw();

                    int rulesTextHeight = 30 * 12 + 50;
                    int returnButtonY = 20 + rulesTextHeight;

                    while (true) {
                        while (!peekmessage(&msg, EX_MOUSE));
                        if (msg.message == WM_LBUTTONDOWN &&
                            isMouseOverButton(300, returnButtonY, 200, 50, msg)) {
                            break;
                        }
                    }
                    break;
                }
                else if (isMouseOverButton(300, 400, 200, 50, msg)) {
                    return true;
                }
            }
        }
    }
}

class GameScene {
public:
    static const int CARD_WIDTH = 100;
    static const int CARD_HEIGHT = 140;
    static const int CARD_SLOT_WIDTH = 120;
    static const int CARD_SLOT_HEIGHT = 160;
    static const int SCORE_BOX_WIDTH = 120;
    static const int SCORE_BOX_HEIGHT = 80;
    static const int PLAYER_AREA_Y = 270;
    static const int BUTTON_AREA_Y = 450;

    static void drawInterface(Player& player, Player& dealer, int chips, int bet, bool hideFirstCard, const std::wstring& message, bool usedDoubleDown);
    static void drawActionButtons(bool canDoubleDown);
    static void drawCardAnimation(int x, int y, const Card& card, bool isDealer, bool hideCard);
    static void drawCardSlots(bool isDealer, int score, bool hideScore);
    static void drawCard(int x, int y, const Card& card, bool isDealer, bool hideCard);

private:
    static void drawBackground() {
        setfillcolor(RGB(0, 100, 0));
        solidrectangle(0, 0, 800, 600);
        setlinecolor(WHITE);
        setlinestyle(PS_SOLID, 3);
        line(0, 250, 800, 250);
    }
};

void GameScene::drawCardSlots(bool isDealer, int score, bool hideScore) {
    int startY = isDealer ? 50 : PLAYER_AREA_Y;

    // 绘制黑色分数框
    setfillcolor(BLACK);
    setlinecolor(BLACK);
    fillroundrect(50, startY, 50 + SCORE_BOX_WIDTH, startY + SCORE_BOX_HEIGHT, 10, 10);

    // 绘制分数
    settextstyle(36, 0, _T("Consolas"));
    setbkmode(TRANSPARENT);
    settextcolor(WHITE);

    if (hideScore) {
        outtextxy(70, startY + 20, _T("??"));
    }
    else {
        TCHAR scoreStr[10];
        _stprintf_s(scoreStr, _T("%d"), score);
        outtextxy(70, startY + 20, scoreStr);
    }

    // 绘制5个空心卡牌槽
    setfillcolor(BLACK);
    setlinestyle(PS_SOLID, 2);
    setlinecolor(WHITE);

    for (int i = 0; i < 5; i++) {
        rectangle(200 + i * CARD_SLOT_WIDTH,
            startY + (CARD_SLOT_HEIGHT - CARD_HEIGHT) / 2,
            200 + i * CARD_SLOT_WIDTH + CARD_WIDTH,
            startY + (CARD_SLOT_HEIGHT - CARD_HEIGHT) / 2 + CARD_HEIGHT);
    }
}

void GameScene::drawCard(int x, int y, const Card& card, bool isDealer, bool hideCard) {
    int adjustedY = y + (CARD_SLOT_HEIGHT - CARD_HEIGHT) / 2;

    if (hideCard && isDealer) {
        putimage(x, adjustedY, &MainMenu::getCardBackImage());
        return;
    }

    // 绘制牌面
    setfillcolor(WHITE);
    setlinecolor(BLACK);
    fillroundrect(x, adjustedY, x + CARD_WIDTH, adjustedY + CARD_HEIGHT, 10, 10);

    // 设置花色颜色
    COLORREF suitColor = (card.suit == HEARTS || card.suit == DIAMONDS) ? RED : BLACK;
    settextcolor(suitColor);

    // 绘制花色和点数（放大并居中）
    std::wstring suitSymbol;
    switch (card.suit) {
    case HEARTS: suitSymbol = L"♥"; break;
    case DIAMONDS: suitSymbol = L"♦"; break;
    case CLUBS: suitSymbol = L"♣"; break;
    case SPADES: suitSymbol = L"♠"; break;
    }

    std::wstring cardText = suitSymbol + ((card.rank == "10") ? L"10" : std::wstring(1, card.rank[0]));

    // 设置更大的字体
    settextstyle(36, 0, _T("Consolas"));

    // 计算文本位置使其居中
    int textWidth = textwidth(cardText.c_str());
    int textHeight = textheight(cardText.c_str());
    int textX = x + (CARD_WIDTH - textWidth) / 2;
    int textY = adjustedY + (CARD_HEIGHT - textHeight) / 2;

    outtextxy(textX, textY, cardText.c_str());
}

void GameScene::drawCardAnimation(int x, int y, const Card& card, bool isDealer, bool hideCard) {
    const int steps = 40;
    const int startX = 800;
    const int endX = x;
    const int adjustedY = y + (CARD_SLOT_HEIGHT - CARD_HEIGHT) / 2;

    // 保存动画前的界面
    IMAGE buffer;
    getimage(&buffer, 0, 0, 800, 600);

    for (int i = 0; i <= steps; i++) {
        BeginBatchDraw();

        // 恢复原始界面
        putimage(0, 0, &buffer);

        // 计算当前帧位置
        int currentX = startX + (endX - startX) * i / steps;

        // 如果是庄家的牌且需要隐藏，则始终显示牌背
        if (isDealer && hideCard) {
            putimage(currentX, adjustedY, &MainMenu::getCardBackImage());
        }
        else {
            // 否则正常绘制牌面
            drawCard(currentX, y, card, isDealer, false);
        }

        FlushBatchDraw();
        EndBatchDraw();

        Sleep(5);
    }
}

void GameScene::drawActionButtons(bool canDoubleDown) {
    // 按钮样式（黑框白底黑字）
    setfillcolor(WHITE);
    setlinecolor(BLACK);
    settextcolor(BLACK);
    settextstyle(20, 0, _T("Consolas"));
    setlinestyle(PS_SOLID, 1);

    // 要牌按钮
    fillrectangle(300, BUTTON_AREA_Y, 400, BUTTON_AREA_Y + 50);
    rectangle(300, BUTTON_AREA_Y, 400, BUTTON_AREA_Y + 50);
    int hitTextWidth = textwidth(_T("要牌"));
    outtextxy(350 - hitTextWidth / 2, BUTTON_AREA_Y + 15, _T("要牌"));

    // 停牌按钮
    fillrectangle(420, BUTTON_AREA_Y, 520, BUTTON_AREA_Y + 50);
    rectangle(420, BUTTON_AREA_Y, 520, BUTTON_AREA_Y + 50);
    int standTextWidth = textwidth(_T("停牌"));
    outtextxy(470 - standTextWidth / 2, BUTTON_AREA_Y + 15, _T("停牌"));

    // 加注按钮（始终显示）
    fillrectangle(540, BUTTON_AREA_Y, 640, BUTTON_AREA_Y + 50);
    rectangle(540, BUTTON_AREA_Y, 640, BUTTON_AREA_Y + 50);
    int doubleTextWidth = textwidth(_T("加注"));

    if (canDoubleDown) {
        settextcolor(BLACK);
        outtextxy(590 - doubleTextWidth / 2, BUTTON_AREA_Y + 15, _T("加注"));
    }
    else {
        // 不可加注时变灰
        setfillcolor(RGB(200, 200, 200));
        solidrectangle(540, BUTTON_AREA_Y, 640, BUTTON_AREA_Y + 50);
        settextcolor(RGB(100, 100, 100));
        outtextxy(590 - doubleTextWidth / 2, BUTTON_AREA_Y + 15, _T("加注"));
    }

    FlushBatchDraw();
}

void GameScene::drawInterface(Player& player, Player& dealer, int chips, int bet, bool hideFirstCard, const std::wstring& message, bool usedDoubleDown) {
    BeginBatchDraw();

    // 绘制背景
    drawBackground();

    // 设置统一文字样式（与"庄家手牌"相同大小）
    settextstyle(24, 0, _T("Consolas"));
    settextcolor(WHITE);
    setbkmode(TRANSPARENT);

    // 绘制庄家区域
    outtextxy(50, 20, _T("庄家手牌:"));
    drawCardSlots(true, dealer.getScore(), hideFirstCard);

    // 绘制玩家区域（"你的手牌"下移至黑框下方）
    settextstyle(24, 0, _T("Consolas"));
    outtextxy(50, GameScene::PLAYER_AREA_Y + GameScene::SCORE_BOX_HEIGHT + 10, _T("你的手牌:"));
    drawCardSlots(false, player.getScore(), false);

    // 绘制筹码和赌注信息（贴右上角）
    settextstyle(20, 0, _T("Consolas"));
    TCHAR buffer[100];
    _stprintf_s(buffer, _T("筹码: %d"), chips);
    outtextxy(800 - textwidth(buffer) - 20, 10, buffer);  // 右上角
    settextstyle(20, 0, _T("Consolas"));
    _stprintf_s(buffer, _T("赌注: %d"), bet);
    outtextxy(800 - textwidth(buffer) - 20, 30, buffer);  // 筹码下方

    // 绘制消息
    if (!message.empty()) {
        settextcolor(YELLOW);
        outtextxy(400 - textwidth(message.c_str()) / 2, 200, message.c_str());
    }

    // 绘制玩家手牌
    for (size_t i = 0; i < player.getHand().size(); ++i) {
        drawCard(200 + i * CARD_SLOT_WIDTH, PLAYER_AREA_Y, player.getHand()[i], false, false);
    }

    // 绘制庄家手牌
    for (size_t i = 0; i < dealer.getHand().size(); ++i) {
        bool hide = (i == 0 && hideFirstCard);
        drawCard(200 + i * CARD_SLOT_WIDTH, 50, dealer.getHand()[i], true, hide);
    }

    // 绘制操作按钮（不再限制手牌数）
    bool canDoubleDown = !usedDoubleDown && (chips >= bet * 2);
    drawActionButtons(canDoubleDown);

    FlushBatchDraw();
    EndBatchDraw();
}

class Game {
private:
    Deck deck;
    Player player;
    Player dealer;
    int playerChips = 100;
    int betAmount = 10;
    bool usedDoubleDown = false; // 标记是否已加注

public:
    Game() {
        initgraph(800, 600);
        MainMenu::loadResources();
        BeginBatchDraw();
    }

    ~Game() {
        EndBatchDraw();
        closegraph();
    }

    void start() {
        while (true) {
            bool shouldExit = MainMenu::show();
            if (shouldExit) {
                break;
            }

            bool gameOver = false;

            while (!gameOver) {
                if (playerChips < 10) {
                    cleardevice();
                    setbkcolor(WHITE);
                    cleardevice();
                    settextcolor(BLACK);
                    settextstyle(36, 0, _T("Consolas"));
                    outtextxy(250, 250, _T("筹码不足，游戏结束！"));
                    FlushBatchDraw();
                    Sleep(2000);
                    gameOver = true;
                    continue;
                }

                if (playerChips >= 200) {
                    cleardevice();
                    setbkcolor(WHITE);
                    cleardevice();
                    settextcolor(BLACK);
                    settextstyle(36, 0, _T("Consolas"));
                    outtextxy(200, 250, _T("恭喜！你达到了200筹码，游戏胜利！"));
                    FlushBatchDraw();
                    Sleep(2000);
                    gameOver = true;
                    continue;
                }

                betAmount = 10;
                bool roundOver = false;
                usedDoubleDown = false; // 每回合重置加注状态
                bool canHitOrStand = true;

                player.clearHand();
                dealer.clearHand();

                // 绘制初始界面（没有牌）
                GameScene::drawInterface(player, dealer, playerChips, betAmount, true, L"", usedDoubleDown);
                FlushBatchDraw();

                // 发牌动画（先动画，再添加到手牌）
                for (int i = 0; i < 2; i++) {
                    // 玩家牌
                    Card card = deck.dealCard();
                    GameScene::drawCardAnimation(200 + i * GameScene::CARD_SLOT_WIDTH,
                        GameScene::PLAYER_AREA_Y,
                        card,
                        false,
                        false);
                    player.addCard(card);

                    // 庄家牌
                    Card dealerCard = deck.dealCard();
                    bool hideDealerCard = (i == 0);  // 只有第一张庄家牌需要隐藏
                    GameScene::drawCardAnimation(200 + i * GameScene::CARD_SLOT_WIDTH,
                        50,
                        dealerCard,
                        true,
                        hideDealerCard);
                    dealer.addCard(dealerCard);

                    // 更新界面
                    GameScene::drawInterface(player, dealer, playerChips, betAmount, true, L"", usedDoubleDown);
                    FlushBatchDraw();

                    Sleep(300);
                }

                // 检查玩家是否天胡或5张未爆
                if (player.getScore() == 21 || player.hasFiveCardsNotBust()) {
                    bool dealerBlackjack = dealer.getScore() == 21;

                    if (dealerBlackjack && !player.hasFiveCardsNotBust()) {
                        GameScene::drawInterface(player, dealer, playerChips, betAmount, false, L"平局！", usedDoubleDown);
                        playerChips += 0;
                    }
                    else {
                        playerChips += betAmount;
                        GameScene::drawInterface(player, dealer, playerChips, betAmount, false,
                            player.hasFiveCardsNotBust() ? L"5张未爆，你赢了！" : L"21点！你赢了！", usedDoubleDown);
                    }
                    FlushBatchDraw();
                    Sleep(2000);
                    roundOver = true;
                }

                while (!roundOver) {
                    ExMessage msg;
                    while (!peekmessage(&msg, EX_MOUSE));

                    // 检查是否还能加注（仅限一次，且筹码足够）
                    bool canStillDoubleDown = !usedDoubleDown && (playerChips >= betAmount * 2);

                    if (canHitOrStand && msg.message == WM_LBUTTONDOWN &&
                        msg.x >= 300 && msg.x <= 400 &&
                        msg.y >= GameScene::BUTTON_AREA_Y && msg.y <= GameScene::BUTTON_AREA_Y + 50) {

                        Card card = deck.dealCard();
                        int slotIndex = player.getHand().size();

                        GameScene::drawCardAnimation(200 + slotIndex * GameScene::CARD_SLOT_WIDTH,
                            GameScene::PLAYER_AREA_Y,
                            card,
                            false,
                            false);
                        player.addCard(card);

                        // 更新界面（不再限制手牌数）
                        GameScene::drawInterface(player, dealer, playerChips, betAmount, true, L"", usedDoubleDown);
                        FlushBatchDraw();
                        Sleep(500);

                        if (player.getScore() > 21) {
                            playerChips -= betAmount;
                            GameScene::drawInterface(player, dealer, playerChips, betAmount, false, L"爆牌！你输了！", usedDoubleDown);
                            FlushBatchDraw();
                            Sleep(2000);
                            roundOver = true;
                            canHitOrStand = false;
                        }
                        else if (player.getScore() == 21 || player.hasFiveCardsNotBust()) {
                            while (dealer.getScore() < 17) {
                                Card dealerCard = deck.dealCard();
                                int dealerSlotIndex = dealer.getHand().size();

                                GameScene::drawCardAnimation(200 + dealerSlotIndex * GameScene::CARD_SLOT_WIDTH,
                                    50,
                                    dealerCard,
                                    true,
                                    false);
                                dealer.addCard(dealerCard);

                                GameScene::drawInterface(player, dealer, playerChips, betAmount, false, L"庄家要牌...", usedDoubleDown);
                                FlushBatchDraw();
                                Sleep(1000);
                            }

                            if (dealer.getScore() > 21 ||
                                dealer.getScore() < player.getScore() ||
                                player.hasFiveCardsNotBust()) {
                                playerChips += betAmount;
                                GameScene::drawInterface(player, dealer, playerChips, betAmount, false,
                                    player.hasFiveCardsNotBust() ? L"5张未爆，你赢了！" : L"你赢了！", usedDoubleDown);
                            }
                            else if (dealer.getScore() == player.getScore()) {
                                GameScene::drawInterface(player, dealer, playerChips, betAmount, false, L"平局！", usedDoubleDown);
                            }
                            else {
                                playerChips -= betAmount;
                                GameScene::drawInterface(player, dealer, playerChips, betAmount, false, L"你输了！", usedDoubleDown);
                            }

                            FlushBatchDraw();
                            Sleep(2000);
                            roundOver = true;
                            canHitOrStand = false;
                        }
                    }
                    else if (canHitOrStand && msg.message == WM_LBUTTONDOWN &&
                        msg.x >= 420 && msg.x <= 520 &&
                        msg.y >= GameScene::BUTTON_AREA_Y && msg.y <= GameScene::BUTTON_AREA_Y + 50) {

                        while (dealer.getScore() < 17) {
                            Card dealerCard = deck.dealCard();
                            int dealerSlotIndex = dealer.getHand().size();

                            GameScene::drawCardAnimation(200 + dealerSlotIndex * GameScene::CARD_SLOT_WIDTH,
                                50,
                                dealerCard,
                                true,
                                false);
                            dealer.addCard(dealerCard);

                            GameScene::drawInterface(player, dealer, playerChips, betAmount, false, L"庄家要牌...", usedDoubleDown);
                            FlushBatchDraw();
                            Sleep(1000);
                        }

                        if (dealer.getScore() > 21 || dealer.getScore() < player.getScore()) {
                            playerChips += betAmount;
                            GameScene::drawInterface(player, dealer, playerChips, betAmount, false, L"你赢了！", usedDoubleDown);
                        }
                        else if (dealer.getScore() == player.getScore()) {
                            GameScene::drawInterface(player, dealer, playerChips, betAmount, false, L"平局！", usedDoubleDown);
                        }
                        else {
                            playerChips -= betAmount;
                            GameScene::drawInterface(player, dealer, playerChips, betAmount, false, L"你输了！", usedDoubleDown);
                        }

                        FlushBatchDraw();
                        Sleep(2000);
                        roundOver = true;
                    }
                    else if (msg.message == WM_LBUTTONDOWN &&
                        msg.x >= 540 && msg.x <= 640 &&
                        msg.y >= GameScene::BUTTON_AREA_Y && msg.y <= GameScene::BUTTON_AREA_Y + 50) {

                        if (!usedDoubleDown && playerChips >= betAmount * 2) {
                            betAmount *= 2;
                            usedDoubleDown = true;
                            GameScene::drawInterface(player, dealer, playerChips, betAmount, true, L"加注成功！", usedDoubleDown);
                            FlushBatchDraw();
                        }
                        else {
                            GameScene::drawInterface(player, dealer, playerChips, betAmount, true,
                                usedDoubleDown ? L"本回合已加注过！" : L"筹码不足，无法加注！", usedDoubleDown);
                            FlushBatchDraw();
                        }
                    }
                }

                if (deck.needReshuffle()) {
                    deck = Deck();
                }
            }
        }
    }
};

int main() {
    Game game;
    game.start();
    return 0;
}